package com.saascloud.core.obs;


import com.obs.services.ObsClient;
import com.obs.services.model.*;
import com.saascloud.config.properties.FileProperties;
import com.saascloud.core.FileTemplate;
import com.saascloud.core.ObsGetResp;
import com.saascloud.core.ObsListItemResp;
import com.saascloud.core.ObsUploadResp;
import com.saascloud.core.saas.SaasContextUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: lidingyi
 * @Contact: one_dream@aliyun.com
 * @Date: 2022/5/20 11:06
 * @Version: 1.0
 * @Description:
 */
public class ObsFileTemplate implements FileTemplate {
    @Autowired
    private FileProperties fileProperties;
    @Autowired
    private Environment environment;
    @Autowired
    private ObsClient obsClient;

    private String applicationName;

    private String defaultBucketName;

    @PostConstruct
    public void init() {
        this.defaultBucketName = fileProperties.getObs().getBucketName();
        this.applicationName = environment.getProperty("spring.application.name");
    }

    @Override
    public ObsUploadResp upload(String objectName, InputStream inputStream) {
        return upload(defaultBucketName, objectName, inputStream);
    }

    @Override
    public ObsUploadResp upload(String bucketName, String objectName, InputStream inputStream) {
        PutObjectResult putObjectResult = obsClient.putObject(bucketName, finalObjName(objectName), inputStream);
        ObsUploadResp obsUploadResp = new ObsUploadResp();
        BeanUtils.copyProperties(putObjectResult, obsUploadResp);
        return obsUploadResp;
    }

    @Override
    public ObsUploadResp upload(String objectName, File file) {
        return upload(defaultBucketName, objectName, file);
    }

    @Override
    public ObsUploadResp upload(String bucketName, String objectName, File file) {
        PutObjectResult putObjectResult = obsClient.putObject(bucketName, finalObjName(objectName), file);
        ObsUploadResp obsUploadResp = new ObsUploadResp();
        BeanUtils.copyProperties(putObjectResult, obsUploadResp);
        return obsUploadResp;
    }

    @Override
    public ObsGetResp getObject(String bucketName, String objectName) {
        ObsObject object = obsClient.getObject(bucketName, finalObjName(objectName));
        ObsGetResp obsGetResp = new ObsGetResp();
        obsGetResp.setBucketName(object.getBucketName());
        obsGetResp.setObjectKey(object.getObjectKey());
        obsGetResp.setObjectContent(object.getObjectContent());
        ObjectMetadata metadata = object.getMetadata();
        ObsGetResp.ObjectMata objectMata = new ObsGetResp.ObjectMata();
        BeanUtils.copyProperties(metadata, objectMata);
        obsGetResp.setMetadata(objectMata);
        return obsGetResp;
    }

    @Override
    public ObsGetResp getObject(String objectName) {
        return getObject(defaultBucketName, objectName);
    }

    @Override
    public List<ObsListItemResp> listObjectsByPrefix(String bucketName, String prefix) {
        ListObjectsRequest request = new ListObjectsRequest();
        request.setBucketName(bucketName);
        request.setPrefix(finalObjName(prefix));
        ObjectListing result;
        List<ObsListItemResp> allObjects = new ArrayList<>();
        do {
            result = obsClient.listObjects(request);
            for (ObsObject obsObject : result.getObjects()) {
                allObjects.add(new ObsListItemResp(obsObject.getObjectKey()));
            }
            request.setMarker(result.getNextMarker());
        } while (result.isTruncated());
        return allObjects;
    }

    @Override
    public List<ObsListItemResp> listObjectsByPrefix(String prefix) {
        return listObjectsByPrefix(defaultBucketName, prefix);
    }


    private String finalObjName(String objectName) {
        String prefix = "";
        if (SaasContextUtil.getTenantId() != null) {
            prefix = SaasContextUtil.getTenantId() + "/";
        }
        if (StringUtils.hasLength(applicationName)) {
            prefix = prefix + applicationName + "/";
        }
        return prefix + objectName;
    }


}
